package com.nian.user.center.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nian.common.base.util.StringUtils;
import com.nian.common.model.Const;
import com.nian.common.model.SerializeUtils;
import com.nian.common.model.ServerResponse;
import com.nian.common.model.SysMessage;
import com.nian.redis.cache.JedisClient;
import com.nian.user.center.config.JwtToken;
import com.nian.user.center.service.IAppUserService;
import com.nian.user.dao.AppUserMapper;
import com.nian.user.model.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zhangmj
 * @since 2020-04-05
 */
@Service
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements IAppUserService {

    @Value("${redis.key.prefix.authCode}")
    private String REDIS_KEY_PREFIX_AUTH_CODE;
    @Value("${redis.key.expire.authCode}")
    private Long AUTH_CODE_EXPIRE_SECONDS;
    @Value("${redis.key.prefix.sessionId}")
    private String REDIS_KEY_PREFIX_SESSION_ID;

    @Value("${jwt.tokenHeader}")
    private String tokenHeader;
    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Autowired
    private JwtToken jwtToken;

    @Autowired
    private JedisClient jedisClient;

    @Override
    public AppUser getByUsername(String userName) {
        return lambdaQuery().eq(AppUser::getUsername, userName).one();
    }

    @Override
    public AppUser getByPhoneNum(String phoneNum) {
        return null;
    }

    @Override
    public ServerResponse register(String userName, String pwd, String phoneNum, String authCode) {
        if(StringUtils.isEmpty(userName)){
            return ServerResponse.createByErrorMessage(SysMessage.USER_NAME_NOT_EMPTY);
        }
        if(StringUtils.isEmpty(pwd)){
            return ServerResponse.createByErrorMessage(SysMessage.PWD_NOT_EMPTY);
        }
        Integer count = lambdaQuery().eq(AppUser::getUsername, userName).count();
        if(count != null && count > Const.INT_ZERO){
            return ServerResponse.createByErrorMessage(SysMessage.USER_NAME_EXIST);
        }
        AppUser appUser = new AppUser();
        appUser.setUsername(userName);
        appUser.setPassword(new BCryptPasswordEncoder().encode(pwd));
        Boolean flag = save(appUser);
        if(flag){
            return ServerResponse.createBySuccess(SysMessage.REGISTER_SUCCESS);
        }
        return ServerResponse.createByErrorMessage(SysMessage.REGISTER_FAIL);
    }

    @Override
    public ServerResponse login(String username, String password) {
        String token = null;
        //密码需要客户端加密后传递
        try {
            AppUser appUser = getByUsername(username);
            if(appUser == null){
                return ServerResponse.createByErrorMessage(SysMessage.USER_NAME_NOT_EXIST);
            }
            if(!new BCryptPasswordEncoder().matches(password, appUser.getPassword())){
                return ServerResponse.createByErrorMessage(SysMessage.ERROR_USERNAME_PWD);
            }
            token = jwtToken.generateToken(appUser);
            this.setRedisSession(appUser);
            Map<String, String> tokenMap = new HashMap<>();
            tokenMap.put("token", token);
            tokenMap.put("tokenHead", tokenHead);
            return ServerResponse.createBySuccess(tokenMap);
        } catch (Exception e) {
            log.error("登录异常:", e);
        }
        return ServerResponse.createByErrorMessage(SysMessage.LOGIN_ERROR);
    }

    @Override
    public ServerResponse generateAuthCode(String phoneNum) {
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 6; i++) {
            sb.append(random.nextInt(10));
        }
        //验证码绑定手机号并存储到 redis
        jedisClient.set(REDIS_KEY_PREFIX_AUTH_CODE + phoneNum, sb.toString());
        jedisClient.expire(REDIS_KEY_PREFIX_AUTH_CODE + phoneNum, AUTH_CODE_EXPIRE_SECONDS.intValue());
        return ServerResponse.createBySuccess("获取验证码成功", sb.toString());
    }

    @Override
    public String refreshToken(String token) {
        return null;
    }

    @Override
    public void logout(AppUser info) {
        String key = REDIS_KEY_PREFIX_SESSION_ID + info.getUsername();
        jedisClient.remove(key);
    }

    private void setRedisSession(AppUser info){
        String key = REDIS_KEY_PREFIX_SESSION_ID + info.getUsername();
        jedisClient.set(key, SerializeUtils.serialize(info));
    }
}
